<?php

namespace beObject\Web;

use beObject\MVC\Model;
use beObject\Primitive\String;
use beObject\Exceptions\FileNotFoundException;

/**
 * This object implements methods to parse and display html templates.
 * @author Dany Mottier
 * @copyright MD Consult
 * @license http://www.gnu.org/licenses/gpl.html
 * @link http://www.beobject-framework.net/beobject/web/template/template-class/<br />
 * @package beObject\Web
 * @version 3.0
 */
class Template
    extends Model {

  /**
   * @var string The extension for all template files.
   */
  protected static $extension = ".tmpl";

  /**
   * @var string The complete (x)html source of the template.
   */
  protected $source = null;

  /**
   * @var string The template filename.
   */
  protected $filename = null;

  /**
   * @var string The delimiter for keys in the source.
   */
  protected static $delimiter = "{.}";

  /**
   * @var string The delimiter for labels in the source.
   */
  protected static $labelDelimiter = "[.]";

  /**
   * Gets the template content.
   * @param beObject\Primitive\String $filename The name of the template.
   * @throws beObject\Exception\FileNotFoundException
   * @link http://www.beobject-framework.net/beobject/web/template/template-__construct/<br />
   */
  public function __construct(String $filename) {
    $this->filename = $filename() . self::$extension;

    if (file_exists($this->filename)) {
      $this->source = file_get_contents($this->filename);
    } else {
      throw new FileNotFoundException("File does not exist");
    }
  }

  /**
   * Returns template extension.
   * @return beObject\Primitive\String Returns the template extension.
   * @link http://www.beobject-framework.net/beobject/web/template/template-getextension/
   */
  public function getExtension() {
    return new String(self::$extension);
  }

  /**
   * Returns the html source.
   * @return beObject\Primitive\String Returns the html source.
   * @link http://www.beobject-framework.net/beobject/web/template/template-getsource/
   */
  public function getSource() {
    return new String($this->source);
  }

  /**
   * Render the html source.
   * @link http://www.beobject-framework.net/beobject/web/template/template-render/
   */
  public function render() {
    print $this->source;
  }
  
  /**
   * Clear all empty tag values.
   * @link http://www.beobject-framework.net/beobject/web/template/template-clearemptyvalues/
   */
  public function clearEmptyValues() {
    $this->source = preg_replace("#{\w+}#", "", $this->source);
  }

  /**
   * Replace the key by the value in the source.
   * @param beObject\Primitive\String $key The key.
   * @param beObject\Primitive\String $value The value.
   * @link http://www.beobject-framework.net/beobject/web/template/template-setvalue/
   */
  public function setValue(String $key, String $value) {
    $pattern = str_ireplace(".", $key(), self::$delimiter);
    $this->source = preg_replace("@" . $pattern . "@i", $value(), $this->source);
  }

  /**
   * Replaces the key label by the value in the source.
   * @param beObject\Primitive\String $key The key label.
   * @param beObject\Primitive\String $value The value.
   * @link http://www.beobject-framework.net/beobject/web/template/template-setlabel/
   */
  public function setLabel(String $key, String $value) {
    $pattern = str_ireplace(".", $key(), self::$labelDelimiter);
    $this->source = str_ireplace($pattern, $value(), $this->source);
  }

  /**
   * This method allows you to translate a template automatically.<br />
   * If there is a file with the same name of the template and the '.lang'
   * extension, in JSON format, it will be parsed and all notified [label]'s
   * will be replaced with their value in the JSON array.
   * @param beObject\Primitive\String $language The language to use.
   * @link http://www.beobject-framework.net/beobject/web/template/template-translate/
   */
  public function translate(String $language) {
    $file = str_replace(".tmpl", ".lang", $this->filename);

    if (file_exists($file)) {
      $translation = json_decode(file_get_contents($file), true);

      foreach ($translation[$language()] as $key => $value) {
        $this->setLabel(new String($key), new String(utf8_decode($value)));
      }
    } else {
      throw new FileNotFoundException("The file '" . str_replace(".tmpl", ".lang", $this->filename) . "' was not found.");
    }
  }

}

?>
